import { createUser, deleteUser, getUserList, updateUser } from "@/api/user";
import { formatFormItem, FormItemType, FormTableItemType } from "@/components/FormByData/FormByData";
import Table, { TableRef } from "@/components/Table";
import { Card, Space, Button, message, FormInstance, Image } from "antd";
import { MutableRefObject, useEffect, useMemo, useRef, useState } from "react";
import { Operation } from "@/typings/common";
import { formatDate } from "@/utils/date";
import { EditOutlined, EyeOutlined } from "@ant-design/icons";
import FormByData from "@/components/FormByData/FormByData";
import { CreateUserReq, User as UserType, UpdateUserReq } from "@/typings/api/user";
import Search from "@/components/Search";
import Modal from "@/components/Modal/Modal";
import { UploadImg } from "@/components/UploadImg";
import DictionaryColumnRender from "@/components/DictionaryColumnRender";
import RoleSelect from "@/components/RoleSelect";
import { getRoleList } from "@/api/role";
import { Role } from "@/typings/api/role";

type SearchFields = Pick<UserType, "username" | "email" | "nickname">;

const User = () => {
    const [roleList, setRoleList] = useState<Role[]>([]);
    const fetchRoleList = async () => {
        // prettier-ignore
        const { data: { list } } = await getRoleList({ page: 1, pageSize: 9999 });
        setRoleList(list);
    };
    useEffect(() => {
        fetchRoleList();
    }, []);
    const columns = useMemo<FormTableItemType<UpdateUserReq>[]>(
        () => [
            { dataIndex: "username", title: "用户名", required: true },
            { dataIndex: "email", title: "邮箱", required: true },
            {
                dataIndex: "roles",
                title: "角色",
                component: RoleSelect,
                componentProps: { mode: "multiple" },
                render: roleIds => roleIds?.map((_id: string) => roleList.find(item => item._id === _id)?.name).join("，"),
            },
            { dataIndex: "password", title: "密码", isTable: false, required: true },
            {
                dataIndex: "status",
                title: "状态",
                type: "radio",
                render: value => <DictionaryColumnRender dictType="status" value={value} />,
                dictType: "status",
                dictClass: "boolean",
            },
            { dataIndex: "nickname", title: "昵称" },
            {
                dataIndex: "avatar",
                title: "头像",
                render: avatar => <Image preview={{ mask: <EyeOutlined /> }} width={30} height={30} src={avatar} />,
                component: UploadImg,
            },
            { dataIndex: "remark", title: "备注" },
            { dataIndex: "createdAt", title: "创建时间", render: val => formatDate(val), isForm: false },
            { dataIndex: "updatedAt", title: "更新时间", render: val => formatDate(val), isForm: false },
            { dataIndex: "operation", isForm: false, title: "操作", fixed: "right" },
        ],
        [roleList]
    );

    const [modalShow, setModalShow] = useState(false);
    const [opType, setOpType] = useState<Operation>("add");
    const currentRecord = useRef<UpdateUserReq>();

    const handleAdd = () => {
        setOpType("add");
        setModalShow(true);
        formRef.current?.resetFields();
    };

    const clickEdit = (record: UpdateUserReq) => {
        setOpType("edit");
        setModalShow(true);
        formRef.current?.resetFields();
        setTimeout(() => {
            formRef.current?.setFieldsValue(record);
        });
        currentRecord.current = record;
    };

    const tableRef = useRef<TableRef>(null);
    const formRef: MutableRefObject<FormInstance<UpdateUserReq> | null> = useRef(null);
    const submit = async () => {
        const formData = await formRef.current?.validateFields?.();
        if (!formData) return;
        if (opType === "add") {
            await createUser(formData as CreateUserReq);
            message.success("创建成功");
        } else {
            if (!currentRecord.current) return;
            await updateUser({ ...formData, _id: currentRecord.current._id });
            message.success("编辑成功");
        }
        tableRef.current?.getList();
        setModalShow(false);
    };

    const searchFormItems: FormItemType[] = [
        { label: "用户名", name: "username" },
        { label: "邮箱", name: "email" },
        { label: "昵称", name: "nickname" },
    ];
    const searchParams = useRef<Partial<UserType>>({});
    const handleSearch = async (formData: SearchFields) => {
        searchParams.current = formData;
        await tableRef.current?.getList(1, 10);
    };

    const searchFromRef = useRef<FormInstance>();
    const handleReset = () => {
        searchFromRef.current?.resetFields();
        searchParams.current = {};
        tableRef.current?.getList(1, 10);
    };

    return (
        <Card
            title={
                <Search<SearchFields>
                    title="管理端用户管理"
                    formItems={searchFormItems}
                    onReset={handleReset}
                    onAdd={handleAdd}
                    onSearch={handleSearch}
                    getFormRef={ref => (searchFromRef.current = ref)}
                />
            }
        >
            <Table<UpdateUserReq>
                ref={tableRef}
                columns={columns}
                getApi={p => getUserList({ ...p, ...searchParams.current })}
                delApi={deleteUser}
                actionMore={record => (
                    <Space>
                        <Button type="primary" size="small" icon={<EditOutlined />} onClick={() => clickEdit(record)}>
                            编辑
                        </Button>
                    </Space>
                )}
            />

            <Modal title={opType === "add" ? "添加" : "编辑"} open={modalShow} onCancel={() => setModalShow(false)} onOk={submit} forceRender>
                <FormByData
                    getFormRef={ref => (formRef.current = ref)}
                    formItems={formatFormItem(columns)}
                    cols={1}
                    formProps={{ initialValues: { status: true } }}
                />
            </Modal>
        </Card>
    );
};

export default User;
